package com.dhecp.project.logstics.controller;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.dhecp.project.api.util.ApiConfig;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.dhecp.common.annotation.Log;
import com.dhecp.common.annotation.RepeatSubmit;
import com.dhecp.common.config.Global;
import com.dhecp.common.core.domain.AjaxResult;
import com.dhecp.common.core.page.TableDataInfo;
import com.dhecp.common.enums.BusinessType;
import com.dhecp.common.utils.DateUtils;
import com.dhecp.common.utils.TypeUtils;
import com.dhecp.core.constant.ModuleTable;
import com.dhecp.core.layui.GridColumnsPropertyModel;
import com.dhecp.core.utils.ExportExcelUtils;
import com.dhecp.core.utils.PdfUtil;
import com.dhecp.core.utils.ReadExcel;
import com.dhecp.framework.util.ShiroUtils;
import com.dhecp.project.business.domain.FbaPlanOrderDetail;
import com.dhecp.project.business.domain.FbaShipment;
import com.dhecp.project.business.domain.FbaShipmentDetail;
import com.dhecp.project.business.domain.LogisticsMmodeCk;
import com.dhecp.project.business.domain.LogisticsMmodeDetails;
import com.dhecp.project.business.domain.LogisticsMmodeGrads;
import com.dhecp.project.business.domain.ProductActive;
import com.dhecp.project.business.service.FbaPlanOrderService;
import com.dhecp.project.business.service.ProductActiveService;
import com.dhecp.project.common.controller.BaseModuleController;
import com.dhecp.project.hr.domain.OperateCompanyApply;
import com.dhecp.project.hr.service.OperateCompanyApplyService;
import com.dhecp.project.logstics.domain.FbaBox;
import com.dhecp.project.logstics.domain.FbaBoxDetail;
import com.dhecp.project.logstics.mapper.FbaBoxDetailMapper;
import com.dhecp.project.logstics.mapper.FbaBoxMapper;
import com.dhecp.project.logstics.mapper.FbaShipmentDetailMapper;
import com.dhecp.project.logstics.mapper.LogsticsMmodeCkMapper;
import com.dhecp.project.logstics.mapper.LogsticsMmodeDetailsMapper;
import com.dhecp.project.logstics.mapper.LogsticsMmodeGradsMapper;
import com.dhecp.project.logstics.service.FbaBoxDetailService;
import com.dhecp.project.logstics.service.FbaBoxService;
import com.dhecp.project.logstics.service.FbaShipmentService;
import com.dhecp.project.system.domain.SysDictionaryForExport;
import com.dhecp.project.system.domain.SysFilesInfo;
import com.dhecp.project.system.service.SysDictionaryForFieldService;
import com.dhecp.project.system.service.SysFilesInfoService;

import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * @program: kjecp
 * @description: 头程装箱单 控制层
 * @author: hlf
 * @create: 2022-08-15 15:13
 */
@Controller
@RequestMapping("/logstics/fbabox")
public class FbaBoxController extends BaseModuleController {

    private String prefix = "logstics/fbabox";
    private String prefix1 = "business/fbaplanorder";
    private String moduleTable = ModuleTable.FBA_BOX;
    private String moduleTableS = ModuleTable.FBA_BOXS;
    private String moduleTablefh = ModuleTable.FBA_BOXFH;
    private String moduleTable2 = ModuleTable.FBA_BOX_DETAIL;
    private String moduleTable4 = ModuleTable.FBA_PLAN_ORDER;

//    private String moduleTable_Basis = ModuleTable.PRODUCT_BASIS;

    @Autowired
    private FbaBoxMapper fbaBoxMapper;
    @Autowired
    private FbaBoxDetailMapper fbaBoxDetailMapper;
    
    @Autowired
    private FbaBoxService fbaBoxService;
    @Autowired
    private FbaShipmentService fbaShipmentService;
//    @Autowired
//    private ModuleNidAndBidService moduleNidAndBidService;

    @Autowired
    private GridColumnsPropertyModel gridColumnsPropertyModel;

    @Autowired
    private SysDictionaryForFieldService dictionaryForFieldService;

    @Autowired
    private FbaBoxDetailService fbaBoxDetailService;

    @Autowired
    private FbaPlanOrderService fbaPlanOrderService;

    @Autowired
    private OperateCompanyApplyService operateCompanyApplyService;
    @Autowired
    private SysFilesInfoService sysFilesInfoService;
//    @Autowired
//    private ProductBasisService productBasisService;
    @Autowired
    private ProductActiveService productActiveService;

    @Autowired
    private FbaShipmentDetailMapper fbaShipmentDetailMapper;

    @Autowired
    private LogsticsMmodeGradsMapper logsticsMmodeGradsMapper;

    @Autowired
    private LogsticsMmodeDetailsMapper logsticsMmodeDetailsMapper;

    @Autowired
    private LogsticsMmodeCkMapper logsticsMmodeCkMapper;

    /**
     * @Description: 打开查询列表页
     * @Param: [params]
     * @return: org.springframework.web.servlet.ModelAndView
     * @Author: hlf
     * @date: 2022-08-15 15:42
     */
    @RequiresPermissions("business:fbaplanorder:view")
    @GetMapping()
    public ModelAndView view(@RequestParam Map<String, Object> params) {
        params.put("moduleTable", moduleTable);
        params.put("entity", new FbaBox()); //生成表格gridColumns对应的实体，用于获取实体属性生成表格字段
        params.put("prefix", prefix + "/fbabox"); //页面路径
        params.put("toolBarWidth", 200);

        ModelAndView mv = this.openListPage(params);
        mv.addObject("business", "fbabox");
        return mv;
    }

    /**
     * @Description: 打开制单页
     * @Param: nid 必要参数：单据编码（新增时传默认值 0 ，修改、查看时传单据实际值）
     * @return: org.springframework.web.servlet.ModelAndView
     * @Author: hlf
     * @date: 2022-08-15 15:42
     */
    @RequiresPermissions("business:fbaplanorder:view")
    @GetMapping("/edit")
    public ModelAndView editPage(@RequestParam Map<String, Object> params) {
        if (params.get("nid") == null || params.get("nid") == "") {
            params.put("nid", "0");
        }
        params.put("moduleTable", moduleTable);
        params.put("entity", new FbaBox()); //用于获取实体属性名取代对应字典字段名，解决大小写敏感问题
        params.put("moduleUrl", prefix); //页面上级路径
//        params.put("prefix", prefix + "/fbabox_edit"); //页面路径
        Subject userSubject = ShiroUtils.getSubject();
        int enableEdit = 0;
        boolean vType = false;
        if (params.get(enableEdit) == null || "1".equals(params.get(enableEdit).toString())) {
            if (userSubject.isPermitted("logstics:fbabox:edit")) { //当前登录用户主体是否有修改的权限
                enableEdit = 1;
            }
        }

        try {
            Map<String, Object> headData = new HashMap<String, Object>();        //表头的业务数据
//          SysModuleSet moduleSet = sysModuleSetService.queryModuleSet(params);//单据设置信息
            FbaBox entityData = fbaBoxService.queryFirstRecord(params);
            if (entityData.getCreationMethod().equals("自动")){
                params.put("prefix", prefix + "/fbabox_auto"); //页面路径
            }else{
                params.put("prefix", prefix + "/fbabox_add1"); //页面路径
            }
            entityData.setAttention3("实际物流运费=实际计重费+实际材质附加费+实际品名附加费+实际清关费");
            entityData.setAttention4("抛重>实重，实际计重费=MIN(实际计重*计重单价,抛货计重费)+仓库附加计重费用；抛重<=实重，实际计重费=实际计重*计重单价+仓库附加计重费用；计重单价=梯度计重单价+抛货计重单价");
            entityData.setAttention5("实际材质附加费=实际计重*材质附加单价");
            entityData.setAttention7("实际品名附加费=超品名数*品名附加费单价");
            entityData.setAttention9("实际清关费=清关费单价*品名占比");
            entityData.setAttention13("实际抛发物流运费=实际抛发计重运费+实际抛发材质附加费+实际抛发品名附加费+实际抛发清关费");
            entityData.setAttention14("实际抛发计重运费=MAX（装箱抛重，单票起重）*抛发计重单价+抛发仓库附加计重费；抛发仓库附加计重费=MAX（装箱抛重，单票起重）*仓库附加计重单价");
            entityData.setAttention15("实际抛发材质附加费=MAX（装箱抛重，单票起重）*材质附加单价");
            entityData.setAttention16("实际抛发品名附加费=超品名数量*品名附加费单价");
            entityData.setAttention17("实际抛发清关费=清关费单价");
//            entityData.setNumFreeProNameNew(Integer.valueOf(entityData.getNumFreeProName()));
            headData = TypeUtils.entityToMap(entityData);
            params.put("headData", headData); //表头的业务数据

            params.put("checkBox", "yes"); //生成表格gridColumns时包含复选
            ModelAndView mv = this.openEditPage(params);
            mv.addObject("headData", headData);
            mv.addObject("nowTimeStr", DateUtils.getDate());    //当前日期
            if (entityData.getState().equals("1")){
                mv.addObject("enableEdit",0);
            } else {
                mv.addObject("enableEdit",1); //当前页面是否可编辑（0：不可编辑，1：可编辑）
            }
            if (entityData.getState().equals("1") || entityData.getState().equals("2") || entityData.getState().equals("3")){
                mv.addObject("mjbtnSave",0);
            } else {
                mv.addObject("mjbtnSave",1); //修改装箱清单是否可编辑（0：不可编辑，1：可编辑）
            }
            if (entityData != null) {
                Map<String, Object> params2 = new HashMap<String, Object>();
                params2.put("moduleTable", moduleTable2);
                params2.put("codeShipment",entityData.getCodeShipment());
                params2.put("codeBox",entityData.getCode());
                params2.put("num","1");
                if (entityData.getCreationMethod().equals("自动")){
                    mv.addObject("List", fbaBoxDetailService.queryAutoList(params2));//母件数据

                }else{
                    mv.addObject("List", fbaBoxDetailService.queryList(params2));//母件数据
                }
//                mv.addObject("numFreeProName", entityData.getNumFreeProName());//免费品名字段
//                Map<String, Object> param4 = new HashMap<String, Object>();
//                param4.put("moduleTable", "TP_LOGSTICSPATTERNDETAILS");
//                param4.put("code", entityData.getCodeLogsticsPattern());
//                mv.addObject("textureList", logsticsPatternDetailsService.queryList(param4));//免费品名字段

                //获取物流方式详情
                Map<String, Object> params4 = new HashMap<String, Object>();
                params4.put("logisticsMmodeGuid",entityData.getLogisticsMmodeGuid());
                List<LogisticsMmodeDetails> logisticsMmodeDetailsList = logsticsMmodeDetailsMapper.findLogisticsMmodeDetails(params4);
                List<LogisticsMmodeCk> logisticsMmodeCkList = logsticsMmodeCkMapper.findLogisticsMmodeCk(params4);
                //获取物流方式梯度
                List<LogisticsMmodeGrads> logisticsMmodeGradList = logsticsMmodeGradsMapper.findLogisticsMmodeGrads(params4);
                List<LogisticsMmodeGrads> logisticsMmodeGrads  = logisticsMmodeGradList.stream().filter(logisticsMmodeGrads1 ->
                        "WLFS".equals(logisticsMmodeGrads1.getType())).collect(Collectors.toList());
                List<LogisticsMmodeGrads> logisticsMmodeInfoItems  = logisticsMmodeGradList.stream().filter(logisticsMmodeGrads1 ->
                        "WLFSTDJZ".equals(logisticsMmodeGrads1.getType())).collect(Collectors.toList());

                params4.remove("logisticsMmodeGuid");
                params4.put("type","WLPMTD");
                //获取品名梯度详情
                List<LogisticsMmodeGrads> wlpmtdList = logsticsMmodeGradsMapper.findLogisticsMmodeGrads(params4);

                mv.addObject("textureList",logisticsMmodeDetailsList);
                mv.addObject("logisticsMmodeCkList",logisticsMmodeCkList);
                mv.addObject("logisticsMmodeGrads",logisticsMmodeGrads);
                mv.addObject("wlpmtdList",wlpmtdList);
                mv.addObject("logisticsMmodeInfoItems",logisticsMmodeInfoItems);
            }
            //取子件列表网格
            params.put("moduleTable", moduleTable2);
            params.put("entity", new FbaBoxDetail()); //生成表格gridColumns对应的实体，用于获取实体属性生成表格字段
            params.put("readOnly", vType);//生成列是否可编辑
            params.put("toolBarWidth", 0);//操作区
            params.put("getFieldAttributesType", "pageingrid");//pageingrid：网格字段
            mv.addObject("gridColumnsZJ", gridColumnsPropertyModel.queryGridColumnsPropertyModel(params));

            return mv;
        } catch (Exception e) {
            return this.gotoModelAndViewErrorPage(e.getMessage());    //详细信息
        }

    }

    /**
     * @Description: 查询页 列表数据
     * @Param: [params]
     * @return: com.dhecp.common.core.page.TableDataInfo
     * @Author: hlf
     * @date: 2022-08-15 15:43
     */
    @RequiresPermissions("business:fbaplanorder:list")
    @GetMapping("/list")
    @ResponseBody
    public TableDataInfo list(@RequestParam Map<String, Object> params) {
        if (params.get("num").equals("1")){
            params.put("moduleTable", moduleTableS);
        } else {
            params.put("moduleTable", moduleTable);
        }
        List<FbaBox> list = new ArrayList<FbaBox>();
        try {
            list = fbaBoxService.queryList(params);
        } catch (Exception e) {
            e.printStackTrace();
            return getDataTable(this.getExceptionMessage(e).toString());
        }
        return getDataTable(list);
    }

//    /**
//     * @Description: 查询页 子列表数据
//     * @Param: [params]
//     * @return: com.dhecp.common.core.page.TableDataInfo
//     * @Author: hlf
//     * @date: 2022-08-15 15:43
//     */
//    @RequiresPermissions("logstics:fbabox:sonlist")
//    @GetMapping("/sonlist")
//    @ResponseBody
//    public AjaxResult sonlist(@RequestParam Map<String, Object> params) {
//        try {
//            params.put("moduleTable", moduleTable2);
//            params.put("entity", new FbaBoxDetail()); //生成表格gridColumns对应的实体，用于获取实体属性生成表格字段
//            params.put("toolBarWidth", 0);
////            if (params.get("pagetype") != null && params.get("pagetype").toString().equalsIgnoreCase("checkbox"))
////                params.put("checkBox", "yes");
////            else params.put("radio", "yes");
//            AjaxResult ajaxResult = new AjaxResult();
//            Map<String, Object> dictionaryForFieldMap = new HashMap<String, Object>();
//            Map<String, Object> mapList = new HashMap<>();
//            mapList.put("sonList", fbaBoxService.querySonList(params));
//            mapList.put("fields", TypeUtils.mapToJson(dictionaryForFieldMap));
//            mapList.put("gridColumns", gridColumnsPropertyModel.queryGridColumnsPropertyModel(params));
//            ajaxResult = AjaxResult.success(mapList);
//            return ajaxResult;
//        } catch (Exception e) {
//            return AjaxResult.error(this.getExceptionMessage(e));
//        }
//    }


    /**
     * @Description: 数据导出Excel
     * @Param: [params]
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: hlf
     * @date: 2022-08-15 15:43
     */
    @RequiresPermissions("business:fbaplanorder:export")
    @Log(title = "头程装箱数据导出", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult export(@RequestParam Map<String, Object> params) throws Exception {
        String module = "";
        String sheetNamne = "";
        String type = "";
        List<FbaBox> list = null;
        if (params.get("num").equals("4")){
            module = moduleTableS;
            sheetNamne = "追踪编号导入模板";
            type = "template";
        } else if (params.get("num").equals("5")){
            module = moduleTablefh;
            sheetNamne = "批量标记发货模板";
            type = "template";

        } else if (params.get("num").equals("3")){
            params.put("moduleTable",moduleTableS);
            params.put("num","1");
            list = fbaBoxService.queryList(params);
            module = moduleTableS;
            type = "export";
            sheetNamne = "头程完成单数据";
        } else if (params.get("num").equals("2")){
            params.put("moduleTable",moduleTable);
            params.put("num","0");
            list = fbaBoxService.queryList(params);
            module = moduleTable;
            type = "export";
            sheetNamne = "头程装箱并发货单数据";
        }
        params.put("moduleTable", module);
        params.put("entity", new FbaBox());

        params.put("getFieldAttributesType",type);
        List<SysDictionaryForExport> fieldList = dictionaryForFieldService.queryExportFieldList(params);
        ExportExcelUtils<FbaBox> util = new ExportExcelUtils<FbaBox>(moduleTable, new FbaBox());
        return util.exportExcel(list, fieldList, sheetNamne, type);
    }

    /**
     * @Description: 保存数据
     * @Param: infoMap 必要参数：非网格字段（包括头部、底部所有显示和隐藏的字段）
     * @Param: infoItems 必要参数：对应实体类的json格式字符串
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: hlf
     * @date: 2022-08-15 15:44
     */
    @RequiresPermissions(value = {"business:fbaplanorder:add", "business:fbaplanorder:edit", "business:fbaplanorder:delete"}, logical = Logical.OR)
    @Log(title = "头程装箱单", businessType = BusinessType.UPDATE)
    @PostMapping("/editpost")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult editpost(@RequestParam Map<String, Object> params) {
        params.put("moduleTable", moduleTable);
        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult = fbaBoxService.saveData(params);
        } catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     *@Description: 流转
     *@Param: [params] infoMap 必要参数：非网格字段（包括头部、底部所有显示和隐藏的字段）
     *@Param: [params] infoItems 必要参数：对应实体类的json格式字符串（仅需 guid）
     *@return: com.dhecp.common.core.domain.AjaxResult
     *@Author: hlf
     *@date: 2022-05-09 11:42
     */
    @RequiresPermissions("business:fbaplanorder:flow")
    @Log(title = "装箱", businessType = BusinessType.FLOWGO)
    @PostMapping("/flowgopost")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult flowGoSave(@RequestParam Map<String, Object> params){
        params.put("moduleTable", moduleTable);
        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult= fbaBoxService.updateFlowGo(params);
        }catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     *@Description: 退回
     *@Param: [params] infoMap 必要参数：非网格字段（包括头部、底部所有显示和隐藏的字段）
     *@Param: [params] 必要参数：对应实体类的json格式字符串（仅需 guid）
     *@return: com.dhecp.common.core.domain.AjaxResult
     *@Author: hlf
     *@date: 2022-05-09 11:42
     */
    @RequiresPermissions("business:fbaplanorder:flow")
    @Log(title = "装箱", businessType = BusinessType.FLOWBACK)
    @PostMapping("/flowbackpost")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult flowBackSave(@RequestParam Map<String, Object> params){
        params.put("moduleTable", moduleTable);
        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult= fbaBoxService.updateFlowBack(params);
        }catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * @Description: 修改审核状态
     * @Param: [params]
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: hlf
     * @date: 2022-08-17 14:55
     */
    @RequiresPermissions("business:fbaplanorder:rollbackState")
    @Log(title = "头程装箱回退", businessType = BusinessType.UPDATE)
    @PostMapping("/rollbackState")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult rollbackState(@RequestParam Map<String, Object> params) {
        params.put("moduleTable", moduleTable);
        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult = fbaBoxService.rollbackState(params);
        } catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * @Description: 修改审核状态
     * @Param: [params]
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: hlf
     * @date: 2022-08-17 14:55
     */
    @RequiresPermissions("business:fbaplanorder:updateState")
    @Log(title = "头程装箱审核", businessType = BusinessType.UPDATE)
    @PostMapping("/updateState")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult updateState(@RequestParam Map<String, Object> params) {
        params.put("moduleTable", moduleTable);
        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult = fbaBoxService.updateFlowGo(params);
        } catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     *
     * @param params
     * @return
     */
    @PostMapping("/generatePeihuoPDF")
    @ResponseBody
    public AjaxResult generatePeihuoPDF(@RequestParam Map<String, Object> params){

        AjaxResult ajaxResult = new AjaxResult();
        	
        try {

            String pdfFileName = "/配货清单.pdf";
        	
            // 生成PDF到指定目录下
            String dir = Global.getProfile();
            String codes = params.get("Codes").toString();
            List<PdfUtil.PeihuoDto.ItemDto> itemArr = new ArrayList<PdfUtil.PeihuoDto.ItemDto>();
            for(String code : codes.split(",")) {
            	Map<String, Object> param = new HashMap<String, Object>();
            	param.put("moduleTable", moduleTable);
            	param.put("entity", new FbaBox());
            	param.put("Code", code);
	            List<FbaBox> listFbaBox = fbaBoxService.queryList(param);
	            
	            if (listFbaBox.size() == 0){
	                return AjaxResult.error("单据不存在,不允许打印!");
	            }
	            FbaBox fbaBox = listFbaBox.get(0);
	
	            String codeFbaPlanOrder = fbaBox.getCodePlan() + "/" + fbaBox.getCode();
	            String codeCompany = fbaBox.getCodeCompany();
	            OperateCompanyApply operateCompanyApply = operateCompanyApplyService.findByGsbm(codeCompany);
	            
	            // 根据货件单号查询fbaShipment
	            FbaShipment fbaShipment = fbaShipmentService.queryByCode(fbaBox.getCodeShipment());
	            String weightPredict = fbaShipment.getWeightRealPredict().setScale(2, BigDecimal.ROUND_HALF_UP) + "kg";
	            String nameCompany = operateCompanyApply.getvGsJc();
	            String nameWLFS = fbaBox.getLogisticsType() + "/" + fbaBox.getNameLogsticsWay();
	            String remark = fbaBox.getvZdbz() != null ? fbaBox.getvZdbz() : "";
	            String creationMethod = fbaBox.getCreationMethod() != null ? fbaBox.getCreationMethod() : "";
	
	            Map<String, Object> paramsSon = new HashMap<String, Object>();
	            paramsSon.put("code", fbaBox.getCodeShipment());
	            paramsSon.put("orderby", "CodeStockLocation asc, t1.CommodityCode asc");
	            List<FbaShipmentDetail> fbaShipmentDetails = fbaShipmentDetailMapper.queryList(paramsSon);
	            List<PdfUtil.PeihuoDto.ItemDto.RowDto> rows = new ArrayList<PdfUtil.PeihuoDto.ItemDto.RowDto>();
	            for(FbaShipmentDetail fbaShipmentDetail : fbaShipmentDetails) {
	                String codeGoods = fbaShipmentDetail.getCommodityCode();
	                String nameGoods = fbaShipmentDetail.getName();
	                String fnsku = fbaShipmentDetail.getFnsku();
	                String numPlanDeliver = fbaShipmentDetail.getNumPlanDeliver().toString();
	                String locationGoods = fbaShipmentDetail.getCodeStockLocation();
	                String locationStock = fbaShipmentDetail.getCodeStockArea();
	                String locationName = fbaShipmentDetail.getCodeStockOn();
	                ProductActive productActive = productActiveService.queryProductActiveByCode(fbaShipmentDetail.getCommodityCode());
					String imgGoods = productActive.getImg();
		        	

		        	String numStockLeft = "" + (fbaShipmentDetail.getNumStock() - fbaShipmentDetail.getNumPlanDeliver());
		        	String signName = fbaShipmentDetail.getSignCode();
	                rows.add(new PdfUtil.PeihuoDto.ItemDto.RowDto(codeGoods, nameGoods, fnsku, numPlanDeliver, locationGoods, locationStock, locationName, imgGoods, numStockLeft, signName));
	            }
	
	            PdfUtil.PeihuoDto.ItemDto itemDto = new PdfUtil.PeihuoDto.ItemDto(codeFbaPlanOrder, codeCompany, weightPredict, nameCompany, nameWLFS, remark, creationMethod, rows);
	            itemArr.add(itemDto);
	
	
	            if (fbaBox.getStatePrint().equals("0")){
	                fbaBox.setStatePrint("1");
	                fbaBox.setStatePrintName("配货清单已打印");
	            }
	            fbaBoxMapper.update(fbaBox);

            }
            
            PdfUtil.PeihuoDto dto = new PdfUtil.PeihuoDto(itemArr);
            PdfUtil.generatePeiHuo(dir, pdfFileName, dto);
            String data = "/profile" + pdfFileName;
            ajaxResult = AjaxResult.success("配货清单打印",data);
        }catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * 生成外箱标PDF
     * @param params
     * @return
     */
    @PostMapping("/generateOuterXiangBiaoPDF")
    @ResponseBody
    public AjaxResult generateOuterXiangBiaoPDF(@RequestParam Map<String, Object> params){

        AjaxResult ajaxResult = new AjaxResult();
        	
        try {

            String bid = params.get("bid").toString();
            String pdfFileName = "/" + bid + ".pdf";

            FbaBox fbaBox = fbaBoxService.queryByBid(bid);
            
            // 生成PDF到指定目录下
            String dir = Global.getProfile();

            //查询详情信息
            Map<String, Object>  params1 = new HashMap<String, Object>();
            params1.put("codeBox", fbaBox.getCode());
            List<FbaBoxDetail> fbaBoxDetailList = fbaBoxDetailMapper.findFbaBoxDetail(params1);
            String weight = "";
            for (int i = 0; i < fbaBoxDetailList.size(); i++) {
            	FbaBoxDetail fbaBoxDetail = fbaBoxDetailList.get(i);
            	weight = weight + fbaBoxDetail.getWeight() + " + ";
			}
            weight = weight.substring(0, weight.length() - 3);
            
            String companyShortName = fbaBox.getvGsJc();
            String nameWLFS = fbaBox.getNameLogsticsWay();
            PdfUtil.OuterXiangBiaoDto dto = new PdfUtil.OuterXiangBiaoDto(companyShortName, nameWLFS, weight);
            PdfUtil.generateOuterXiangBiao(dir, pdfFileName, dto);;
            String data = "/profile" + pdfFileName;
            ajaxResult = AjaxResult.success("外箱标打印", data);
        }catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     *
     * @param params
     * @return
     */
    @PostMapping("/generatePeihuoGoodsTagPDF")
    @ResponseBody
    public AjaxResult generatePeihuoGoodsTagPDF(@RequestParam Map<String, Object> params){

        AjaxResult ajaxResult = new AjaxResult();
        	
        try {

            String pdfFileName = "/配货商品标签.pdf";
        	
            // 生成PDF到指定目录下
            String dir = Global.getProfile();
            String codes = params.get("Codes").toString();
            List<PdfUtil.PeihuoDto.ItemDto> itemArr = new ArrayList<PdfUtil.PeihuoDto.ItemDto>();
            for(String code : codes.split(",")) {
            	Map<String, Object> param = new HashMap<String, Object>();
            	param.put("moduleTable", moduleTable);
            	param.put("entity", new FbaBox());
            	param.put("Code", code);
	            List<FbaBox> listFbaBox = fbaBoxService.queryList(param);
	            
	            if (listFbaBox.size() == 0){
	                return AjaxResult.error("单据不存在,不允许打印!");
	            }
	            FbaBox fbaBox = listFbaBox.get(0);
	
	            String codeFbaPlanOrder = code;
	            String codeCompany = fbaBox.getCodeCompany();
	            OperateCompanyApply operateCompanyApply = operateCompanyApplyService.findByGsbm(codeCompany);
	            
	            // 根据货件单号查询fbaShipment
	            FbaShipment fbaShipment = fbaShipmentService.queryByCode(fbaBox.getCodeShipment());
	            String weightPredict = fbaShipment.getWeightRealPredict().setScale(2, BigDecimal.ROUND_HALF_UP) + "kg";
	            String nameCompany = operateCompanyApply.getvGsJc();
	            String nameWLFS = fbaBox.getLogisticsType() + "/" + fbaBox.getNameLogsticsWay();
	            String remark = fbaBox.getvZdbz() != null ? fbaBox.getvZdbz() : "";
	            String creationMethod = fbaBox.getCreationMethod() != null ? fbaBox.getCreationMethod() : "";
	
	            Map<String, Object> paramsSon = new HashMap<String, Object>();
	            paramsSon.put("code", fbaBox.getCodePlan());
	            paramsSon.put("orderby", "CodeStockLocation asc, t1.CommodityCode asc");
	            List<FbaPlanOrderDetail> listFbaPlanOrderDetail = fbaPlanOrderService.querySonList(paramsSon);
	            List<PdfUtil.PeihuoDto.ItemDto.RowDto> rows = new ArrayList<PdfUtil.PeihuoDto.ItemDto.RowDto>();
	            for(FbaPlanOrderDetail fbaPlanOrderDetail : listFbaPlanOrderDetail) {
	                String codeGoods = fbaPlanOrderDetail.getCommodityCode();
	                String nameGoods = fbaPlanOrderDetail.getName();
	                String fnsku = fbaPlanOrderDetail.getFnsku();
	                String numPlanDeliver = fbaPlanOrderDetail.getNumPlanDeliver().toString();
	                String locationGoods = fbaPlanOrderDetail.getCodeStockLocation();
	                String locationStock = fbaPlanOrderDetail.getCodeStockArea();
	                String locationName = fbaPlanOrderDetail.getCodeStockOn();
	                ProductActive productActive = productActiveService.queryProductActiveByCode(fbaPlanOrderDetail.getCommodityCode());
//	                		productBasisService.queryProductBasisByCode(fbaPlanOrderDetail.getCommodityCode());
					String imgGoods = productActive.getImg();
		        	
//					// 透明标记文件名
//		        	List<SysFilesInfo> listSysFilesInfo = sysFilesInfoService.listSysFilesInfoByFileMark(fbaPlanOrderDetail.getGuid());
//		        	String fileNamesTouming = "";
//		        	if (listSysFilesInfo != null && listSysFilesInfo.size() > 0) {
//			        	for(SysFilesInfo sysFilesInfo : listSysFilesInfo) {
//			        		fileNamesTouming = fileNamesTouming + sysFilesInfo.getFileName() + "\n";
//			        	}
//			        	fileNamesTouming = fileNamesTouming.substring(0, fileNamesTouming.length() - 1);
//					} else {
//						fileNamesTouming = "——";
//					}
		        	String numStockLeft = "" + (fbaPlanOrderDetail.getNumStock() - fbaPlanOrderDetail.getNumPlanDeliver());
		        	String signName = fbaPlanOrderDetail.getIsSign() == null || fbaPlanOrderDetail.getIsSign().length() == 0 ? "否" : fbaPlanOrderDetail.getIsSign();
	                rows.add(new PdfUtil.PeihuoDto.ItemDto.RowDto(codeGoods, nameGoods, fnsku, numPlanDeliver, locationGoods, locationStock, locationName, imgGoods, numStockLeft, signName));
	            }
	
	            PdfUtil.PeihuoDto.ItemDto itemDto = new PdfUtil.PeihuoDto.ItemDto(codeFbaPlanOrder, codeCompany, weightPredict, nameCompany, nameWLFS, remark, creationMethod, rows);
	            itemArr.add(itemDto);

            }
            
            PdfUtil.PeihuoDto dto = new PdfUtil.PeihuoDto(itemArr);
            PdfUtil.generatePeiHuo(dir, pdfFileName, dto);
            String data = "/profile" + pdfFileName;
            ajaxResult = AjaxResult.success("配货清单打印",data);
        }catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * 打印商品标页面
     * @param code 头程计划单号
     * @return
     */
    @GetMapping("/toPrintGoods")
    public ModelAndView toPrintGoods(String code) throws Exception {


        ModelAndView mv = new ModelAndView();
        mv.setViewName(prefix1 + "/toPrintGoods");

        List<ToPrintGoodsDto.RowDto> rows = new ArrayList<ToPrintGoodsDto.RowDto>();
        Map<String, Object> params2 = new HashMap<String, Object>();
        params2.put("code",code);
        params2.put("moduleTable",moduleTable);
        List<FbaBox> listFbaPlanOrder = fbaBoxService.queryList(params2);
        FbaBox fbaBox = listFbaPlanOrder.get(0);
        params2.put("orderby", "CodeStockLocation asc, t1.CommodityCode asc");
        params2.put("code",fbaBox.getCodeShipment());
        List<FbaShipmentDetail> fbaShipmentDetails = fbaShipmentDetailMapper.queryList(params2);
        for(FbaShipmentDetail fbaShipmentDetail : fbaShipmentDetails) {
            String guid = fbaShipmentDetail.getGuid();
            String code2 = fbaShipmentDetail.getCommodityCode();
            String name = fbaShipmentDetail.getName();
            String fnsku = fbaShipmentDetail.getFnsku();
            String asin = fbaShipmentDetail.getAsin();
            String sku = fbaShipmentDetail.getSku();
            String num = fbaShipmentDetail.getNumPlanDeliver().toString();
            String signCode = fbaShipmentDetail.getSignCode();
            String code3 = code;
        	
        	List<SysFilesInfo> listSysFilesInfo = sysFilesInfoService.listSysFilesInfoByFileMark(fbaShipmentDetail.getPdGuid());
        	
        	List<ToPrintGoodsDto.RowDto.FileDto> fileToumingbiaoArr = new ArrayList<ToPrintGoodsDto.RowDto.FileDto>();
        	for(SysFilesInfo sysFilesInfo : listSysFilesInfo) {
        		String link = sysFilesInfo.getFilePath();
        		fileToumingbiaoArr.add(new ToPrintGoodsDto.RowDto.FileDto(link));
                
        	}
        	
        	rows.add(new ToPrintGoodsDto.RowDto(guid, code2, name, fnsku, asin, sku, num, code3,signCode, fileToumingbiaoArr));
        }
        ToPrintGoodsDto dto = new ToPrintGoodsDto(code, rows);
        mv.addObject("dto", dto);
        return mv;
    }

    /**
     * 完成单拆箱
     * @param code 头程计划单号
     * @return
     */
    @GetMapping("/devanningWc")
    public ModelAndView devanningWc(String code) throws Exception {
        ModelAndView mv = new ModelAndView();
        mv.setViewName(prefix1 + "/devanningWc");
        mv.addObject("code", code);
        mv.addObject("ali1688EcpApiUrl", ApiConfig.getAli1688EcpApiUrl());
        mv.addObject("moduleTable", moduleTable4);
        return mv;
    }

    @Data
    @AllArgsConstructor
    public static class ToPrintGoodsDto{
    	private String code;
        private List<RowDto> rows; // 明细

        @Data
        @AllArgsConstructor
        public static class RowDto {
            private String guid; // 头程计划单详情GUID
            private String code; // 商品编码
            private String name; // 商品名称
            private String fnsku; // FNSKU
            private String asin; // ASIN
            private String sku; // SKU
            private String num; // 发货数量
            private String code3; // 装箱编码
            private String signCode; // 透明标记编码
			private List<FileDto> fileToumingbiaoArr; // 透明标文件数组

			@Data
			@AllArgsConstructor
			public static class FileDto {
				private String link;
			}
        }
    }

    /**
     * 生成商品标（PDF格式）
     * @param params
     * @return
     */
    @PostMapping("/generateGoodsPDF")
    @ResponseBody
    public AjaxResult generateGoodsPDF(String guid,String code3){

        AjaxResult ajaxResult = new AjaxResult();
        try {

            FbaPlanOrderDetail fbaPlanOrderDetail = fbaPlanOrderService.queryFbaPlanOrderDetailByGuid(guid);
            if (fbaPlanOrderDetail == null){
                return AjaxResult.error("单据不存在,不允许打印!");
            }

            // 生成PDF到指定目录下
            String dir = Global.getProfile();
            String pdfFileName = "/" + guid + ".pdf";

            String nameEn = fbaPlanOrderDetail.getNameGoodsEn();
            String nameCn = fbaPlanOrderDetail.getName();

            String msg = fbaPlanOrderDetail.getFnsku();
            Integer num = fbaPlanOrderDetail.getNumPlanDeliver();
            PdfUtil.GoodsDto dto = new PdfUtil.GoodsDto(nameEn, nameCn, msg, num);

            PdfUtil.generateGoods(dir, pdfFileName, dto, num);

            String data = "/profile" + pdfFileName;

            Map<String, Object> params = new HashMap<String, Object>();
            params.put("moduleTable", moduleTable);
            params.put("entity", new FbaBox());
            params.put("code",code3);

            List<FbaBox> fbaBoxList = fbaBoxService.queryList(params);
            FbaBox fbaBox = fbaBoxList.get(0);

            if (fbaBox.getStatePrint().equals("0")){
                fbaBox.setStatePrint("2");
                fbaBox.setStatePrintName("商品标已打印");
            } else if (fbaBox.getStatePrint().equals("1")){
                fbaBox.setStatePrint("3");
                fbaBox.setStatePrintName("配货清单和商品标已打印");
            }else if (fbaBox.getStatePrint().equals("2")){
                fbaBox.setStatePrint("2");
                fbaBox.setStatePrintName("商品标已打印");
            }else if (fbaBox.getStatePrint().equals("3")){
                fbaBox.setStatePrint("3");
                fbaBox.setStatePrintName("配货清单和商品标已打印");
            }
            fbaBoxMapper.update(fbaBox);

            ajaxResult = AjaxResult.success(data);
        }catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * 获取商品标打印信息
     * @param params
     * @return
     */
    @PostMapping("/getGoodsPrintInfo")
    @ResponseBody
    public AjaxResult getGoodsPrintInfo(String guid,String code3){

        AjaxResult ajaxResult = new AjaxResult();
        try {

            Map<String, Object> params12 = new HashMap<String, Object>();
            params12.put("guid",guid);
            FbaShipmentDetail fbaShipmentDetail = fbaShipmentDetailMapper.queryFirstByGuid(params12);
            if (fbaShipmentDetail == null){
                return AjaxResult.error("单据不存在,不允许打印!");
            }

            // 生成PDF到指定目录下
            String dir = Global.getProfile();
            String pdfFileName = "/" + guid + ".pdf";

            String nameEn = fbaShipmentDetail.getNameGoodsEn();
            String nameCn = fbaShipmentDetail.getName();

            String msg = fbaShipmentDetail.getFnsku();
            Integer num = fbaShipmentDetail.getNumPlanDeliver();
            PdfUtil.GoodsDto dto = new PdfUtil.GoodsDto(nameEn, nameCn, msg, num);

            PdfUtil.generateGoods(dir, pdfFileName, dto, num);

            Map<String, Object> params = new HashMap<String, Object>();
            params.put("moduleTable", moduleTable);
            params.put("entity", new FbaBox());
            params.put("code",code3);

            ajaxResult = AjaxResult.success(dto);
        }catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * 获取所有商品标打印信息
     * @param params
     * @return
     */
    @PostMapping("/getGoodsPrintInfoAll")
    @ResponseBody
    public AjaxResult getGoodsPrintInfoAll(String code){

        AjaxResult ajaxResult = new AjaxResult();
        try {
            Map<String, Object> paramBox = new HashMap<String, Object>();
            paramBox.put("moduleTable", moduleTable);
            paramBox.put("entity", new FbaBox());
            paramBox.put("code",code);
            List<FbaBox> fbaBoxList = fbaBoxService.queryList(paramBox);
        	FbaBox fbaBox = fbaBoxList.get(0);
            Map<String, Object> params2 = new HashMap<String, Object>();
            params2.put("orderby", "CodeStockLocation asc, t1.CommodityCode asc");
            params2.put("code",fbaBox.getCodeShipment());
            List<FbaShipmentDetail> fbaShipmentDetails = fbaShipmentDetailMapper.queryList(params2);

            List<PdfUtil.GoodsDto> rows = new ArrayList<PdfUtil.GoodsDto>();
            for(FbaShipmentDetail fbaShipmentDetail : fbaShipmentDetails) {
                String nameEn = fbaShipmentDetail.getNameGoodsEn();
                String nameCn = fbaShipmentDetail.getName();

                String msg = fbaShipmentDetail.getFnsku();
                Integer num = fbaShipmentDetail.getNumPlanDeliver();
            	rows.add(new PdfUtil.GoodsDto(nameEn, nameCn, msg, num));
            }
            
             if (fbaBox.getStatePrint().equals("1")) {
                fbaBox.setStatePrint("2");
                fbaBox.setStatePrintName("配货清单和商品标已打印");
            }
            fbaBoxMapper.update(fbaBox);
            ajaxResult = AjaxResult.success(rows);
        }catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * 修改透明标状态
     * @param params
     * @return
     */
    @PostMapping("/doPrintTMBAll")
    @ResponseBody
    public AjaxResult getDoPrintTMBAll(String code){

        AjaxResult ajaxResult = new AjaxResult();
        try {
            Map<String, Object> paramBox = new HashMap<String, Object>();
            paramBox.put("moduleTable", moduleTable);
            paramBox.put("entity", new FbaBox());
            paramBox.put("code",code);
            List<FbaBox> fbaBoxList = fbaBoxService.queryList(paramBox);
            FbaBox fbaBox = fbaBoxList.get(0);

            if (fbaBox.getStatePrint().equals("2")){
                fbaBox.setStatePrint("3");
                fbaBox.setStatePrintName("配货清单和商品标和透明标已打印");
            }
            if (fbaBox.getIsfmb() != null){
                if (fbaBox.getIsfmb() == 0){
                    return ajaxResult = AjaxResult.error("选择单据中无透明标,无需打印!");
                }
            }
            if (fbaBox.getStatePrint().equals("1")){
                return ajaxResult = AjaxResult.error("选择单据中商品标未打印,请核实后在操作!");
            }
            fbaBoxMapper.update(fbaBox);

            ajaxResult = AjaxResult.success();
        }catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * 修改透明标状态
     * @param params
     * @return
     */
    @PostMapping("/doPrintTMB")
    @ResponseBody
    public AjaxResult doPrintTMB(String code){

        AjaxResult ajaxResult = new AjaxResult();
        try {
            Map<String, Object> paramBox = new HashMap<String, Object>();
            paramBox.put("moduleTable", moduleTable);
            paramBox.put("entity", new FbaBox());
            paramBox.put("code",code);
            List<FbaBox> fbaBoxList = fbaBoxService.queryList(paramBox);
            FbaBox fbaBox = fbaBoxList.get(0);

            if (fbaBox.getStatePrint().equals("1")){
                return ajaxResult = AjaxResult.error("选择单据中商品标未打印,请核实后在操作!");
            }

            ajaxResult = AjaxResult.success();
        }catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * 获取配货商品标签打印信息
     * @param params
     * @return
     */
    @PostMapping("/getPeihuoGoodsTagPrintInfo")
    @ResponseBody
    public AjaxResult getPeihuoGoodsTagPrintInfo(String codes){
    	
    	String code = codes.split(",")[0];

        AjaxResult ajaxResult = new AjaxResult();
        try {
        	Map<String, Object> param = new HashMap<String, Object>();
        	param.put("moduleTable", moduleTable);
        	param.put("entity", new FbaBox());
        	param.put("Code", code);
            List<FbaBox> listFbaBox = fbaBoxService.queryList(param);
            if (listFbaBox.size() == 0){
                return AjaxResult.error("单据不存在,不允许打印!");
            }
            FbaBox fbaBox = listFbaBox.get(0);

            List<PdfUtil.PeihuoGoodsTagDto.RowDto> rows = new ArrayList<PdfUtil.PeihuoGoodsTagDto.RowDto>();
        	
            Map<String, Object> params2 = new HashMap<String, Object>();
            params2.put("orderby", "CodeStockLocation asc, t1.CommodityCode asc");
            params2.put("code",fbaBox.getCodeShipment());
            List<FbaShipmentDetail> fbaShipmentDetails = fbaShipmentDetailMapper.queryList(params2);
            for(FbaShipmentDetail fbaShipmentDetail : fbaShipmentDetails) {
            	
            	if (fbaShipmentDetail.getNumStock() - fbaShipmentDetail.getNumPlanDeliver() <= 0) {
					continue;
				}
            	
            	String code2 = fbaShipmentDetail.getCommodityCode();
            	String name = fbaShipmentDetail.getName();
            	String fnsku = fbaShipmentDetail.getFnsku();
            	Integer numPlanDelever = fbaShipmentDetail.getNumPlanDeliver();
            	
            	rows.add(new PdfUtil.PeihuoGoodsTagDto.RowDto(code2, name, fnsku, numPlanDelever));
            }
            
            PdfUtil.PeihuoGoodsTagDto dto = new PdfUtil.PeihuoGoodsTagDto(rows);

            ajaxResult = AjaxResult.success(dto);
        }catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * 导入并直接回填追踪编号单据
     * @param params 必要参数：对应实体类的json格式字符串（导入的字段用户内容）
     * @return
     * @throws Exception
     * @author DH-Xxj
     */
    @Log(title = "头程完成单导入", businessType = BusinessType.EXPORT)
    @PostMapping("/importdatapost")
    @ResponseBody
    public AjaxResult importData(@RequestParam Map<String, Object> params) throws Exception {
        params.put("moduleTable", moduleTable);

        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult= fbaBoxService.importData(params);
        }catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * @Description: 打印发票清单
     * @Param: [params]
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: hlf
     * @date: 2022-08-17 14:55
     */
    @RequiresPermissions("business:fbaplanorder:list")
    @Log(title = "打印发票清单", businessType = BusinessType.EXPORT)
    @PostMapping("/printList")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult printList(@RequestParam Map<String, Object> params) {
        params.put("moduleTable", moduleTable);
        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult = fbaBoxService.printList(params);
        } catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * ex表格导入多个FBA设置状态为标记发货
     * @param params 必要参数：对应实体类的json格式字符串（导入的字段用户内容）
     * @return
     * @throws Exception
     * @author fxz
     */
    @Log(title = "ex表格导入多个FBA设置状态为标记发货", businessType = BusinessType.EXPORT)
    @PostMapping("/batchDelivery")
    @ResponseBody
    public AjaxResult batchDelivery(@RequestParam Map<String, Object> params) throws Exception {
        params.put("moduleTable", moduleTable);

        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult= fbaBoxService.batchDelivery(params);
        }catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }


    /**
     * 贴标人装箱人导入
     * @param params
     * @return
     */
    @PostMapping("/personnelImport")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult personnelImport(@RequestParam Map<String, Object> params) {
        params.put("moduleTable", moduleTable);
        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult = fbaBoxService.personnelImport(params);
        } catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * 修改仓库标识
     * @param params
     * @return
     */
    @PostMapping("/updateDestinationFulfillmentCenter")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult updateDestinationFulfillmentCenter(@RequestParam Map<String, Object> params) {
        params.put("moduleTable", moduleTable);
        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult = fbaBoxService.updateDestinationFulfillmentCenter(params);
        } catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * 标记发货
     * @param params
     * @return
     */
    @PostMapping("/isShipments")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult isShipments(@RequestParam Map<String, Object> params) {
        params.put("moduleTable", moduleTable);
        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult = fbaBoxService.isShipments(params);
        } catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * 完成单审核
     * @param params
     * @return
     */
    @PostMapping("/zxwcShbtn")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult zxwcShbtn(@RequestParam Map<String, Object> params) {
        params.put("moduleTable", moduleTable);
        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult = fbaBoxService.zxwcShbtn(params);
        } catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }


    /**
     * @Description: 是否是自税
     * @Param: [params]
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: fxz
     * @date: 2023-03-10 14:55
     */
    @RequiresPermissions("business:fbaplanorder:list")
    @Log(title = "是否是自税", businessType = BusinessType.EXPORT)
    @PostMapping("/selfTax")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult selfTax(@RequestParam Map<String, Object> params) {
        params.put("moduleTable", moduleTable);
        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult = fbaBoxService.selfTax(params);
        } catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * @Description: 打开分箱制单页
     * @Param: nid 必要参数：单据编码（新增时传默认值 0 ，修改、查看时传单据实际值）
     * @return: org.springframework.web.servlet.ModelAndView
     * @Author: fxz
     * @date: 2023-03-13 19:38
     */
    @RequiresPermissions("business:fbaplanorder:view")
    @GetMapping("/binningEdit")
    public ModelAndView binningEdit(@RequestParam Map<String, Object> params) {
        if (params.get("nid") == null || params.get("nid") == "") {
            params.put("nid", "0");
        }
        params.put("moduleTable", moduleTable);
        params.put("entity", new FbaBox()); //用于获取实体属性名取代对应字典字段名，解决大小写敏感问题
        params.put("moduleUrl", prefix); //页面上级路径
        params.put("prefix", prefix + "/fbabox_binningEdit"); //页面路径
        Subject userSubject = ShiroUtils.getSubject();
        int enableEdit = 0;
        boolean vType = false;
        if (params.get(enableEdit) == null || "1".equals(params.get(enableEdit).toString())) {
            if (userSubject.isPermitted("logstics:fbabox:edit")) { //当前登录用户主体是否有修改的权限
                enableEdit = 1;
            }
        }

        try {
            Map<String, Object> headData = new HashMap<String, Object>();        //表头的业务数据
//          SysModuleSet moduleSet = sysModuleSetService.queryModuleSet(params);//单据设置信息
            FbaBox entityData = fbaBoxService.queryFirstRecord(params);
            if (entityData.getIsBinning().equals("是")){
                return this.gotoModelAndViewErrorPage(entityData.getCode()+"该头程装箱单已分箱,请关闭此页面!");
            }
            entityData.setAttention3("实际物流运费=实际计重费+实际材质附加费+实际品名附加费+实际清关费");
            entityData.setAttention4("抛重>实重，实际计重费=MIN(实际计重*计重单价,抛货计重费)+仓库附加计重费用；抛重<=实重，实际计重费=实际计重*计重单价+仓库附加计重费用；计重单价=梯度计重单价+抛货计重单价");
            entityData.setAttention5("实际材质附加费=实际计重*材质附加单价");
            entityData.setAttention7("实际品名附加费=超品名数*品名附加费单价");
            entityData.setAttention9("实际清关费=清关费单价*品名占比");
            headData = TypeUtils.entityToMap(entityData);
            params.put("headData", headData); //表头的业务数据

            params.put("checkBox", "yes"); //生成表格gridColumns时包含复选
            ModelAndView mv = this.openEditPage(params);
            mv.addObject("headData", headData);
            mv.addObject("nowTimeStr", DateUtils.getDate());    //当前日期
            mv.addObject("enableEdit",0);
            if (entityData != null) {
                Map<String, Object> params2 = new HashMap<String, Object>();
                params2.put("moduleTable", moduleTable2);
                params2.put("codeShipment",entityData.getCodeShipment());
                params2.put("codeBox",entityData.getCode());
                params2.put("num","1");
                mv.addObject("List", fbaBoxDetailService.queryList(params2));//母件数据
                //头程计划单下所有箱子数据
                mv.addObject("binningList",fbaBoxDetailMapper.findFbaBoxDetail(params2));
            }
            //取子件列表网格
            params.put("moduleTable", moduleTable2);
            params.put("entity", new FbaBoxDetail()); //生成表格gridColumns对应的实体，用于获取实体属性生成表格字段
            params.put("readOnly", vType);//生成列是否可编辑
            params.put("toolBarWidth", 0);//操作区
            params.put("getFieldAttributesType", "pageingrid");//pageingrid：网格字段
            mv.addObject("gridColumnsZJ", gridColumnsPropertyModel.queryGridColumnsPropertyModel(params));

            return mv;
        } catch (Exception e) {
            return this.gotoModelAndViewErrorPage(e.getMessage());    //详细信息
        }
    }

    /**
     * @Description: 分箱
     * @Param: infoMap 必要参数：非网格字段（包括头部、底部所有显示和隐藏的字段）
     * @Param: infoItems 必要参数：对应实体类的json格式字符串
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: hlf
     * @date: 2023-03-16 09:51
     */
    @RequiresPermissions(value = {"business:fbaplanorder:add", "business:fbaplanorder:edit", "business:fbaplanorder:delete"}, logical = Logical.OR)
    @Log(title = "头程分箱", businessType = BusinessType.UPDATE)
    @PostMapping("/binningEditpost")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult binningEditpost(@RequestParam Map<String, Object> params) {
        params.put("moduleTable", moduleTable);
        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult = fbaBoxService.binningEditpost(params);
        } catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }


    /**
     * 打印透明标页面
     * @param code 头程计划单号
     * @return
     */
    @GetMapping("/transparentPrinting")
    public ModelAndView transparentPrinting(String code) throws Exception {


        ModelAndView mv = new ModelAndView();
        mv.setViewName(prefix1 + "/transparentPrinting");

        List<ToPrintGoodsDto.RowDto> rows = new ArrayList<ToPrintGoodsDto.RowDto>();
        Map<String, Object> params2 = new HashMap<String, Object>();
        params2.put("code",code);
        params2.put("moduleTable",moduleTable);
        List<FbaBox> listFbaPlanOrder = fbaBoxService.queryList(params2);
        FbaBox fbaBox = listFbaPlanOrder.get(0);
        String guid;
        String code2;
        String name;
        String fnsku;
        String asin;
        String sku;
        String num;
        String code3;
        String signCode;
        List<SysFilesInfo> listSysFilesInfo;
        List<ToPrintGoodsDto.RowDto.FileDto> fileToumingbiaoArr;
        if (fbaBox.getState().equals("0")){
            List<FbaPlanOrderDetail> listFbaPlanOrderDetail = fbaPlanOrderService.queryFbaPlanOrderDetailByCode(fbaBox.getCodePlan());
            for(FbaPlanOrderDetail fbaPlanOrderDetail : listFbaPlanOrderDetail) {
                guid = fbaPlanOrderDetail.getGuid();
                code2 = fbaPlanOrderDetail.getCommodityCode();
                name = fbaPlanOrderDetail.getName();
                fnsku = fbaPlanOrderDetail.getFnsku();
                asin = fbaPlanOrderDetail.getAsin();
                sku = fbaPlanOrderDetail.getSku();
                num = fbaPlanOrderDetail.getNumPlanDeliver().toString();
                signCode = fbaPlanOrderDetail.getSignCode();
                code3 = code;
                listSysFilesInfo = sysFilesInfoService.listSysFilesInfoByFileMark(fbaPlanOrderDetail.getGuid());
                fileToumingbiaoArr = new ArrayList<ToPrintGoodsDto.RowDto.FileDto>();
                for(SysFilesInfo sysFilesInfo : listSysFilesInfo) {
                    String link = sysFilesInfo.getFilePath();
                    fileToumingbiaoArr.add(new ToPrintGoodsDto.RowDto.FileDto(link));

                }

                rows.add(new ToPrintGoodsDto.RowDto(guid, code2, name, fnsku, asin, sku, num, code3, signCode,fileToumingbiaoArr));
            }
        } else {
            //查询详情信息
            Map<String, Object>  params1 = new HashMap<String, Object>();
            params1.put("codeBox",fbaBox.getCode());
            List<FbaBoxDetail> fbaBoxDetailList = fbaBoxDetailMapper.findFbaBoxDetail(params1);
            fbaBoxDetailList = JSON.parseArray(fbaBoxDetailList.get(0).getProductInfo(), FbaBoxDetail.class);
            FbaShipmentDetail fbaShipmentDetail;
            for (FbaBoxDetail fbaBoxDetail : fbaBoxDetailList) {
                guid = fbaBoxDetail.getGuid();
                code2 = fbaBoxDetail.getCommodityCode();
                name = fbaBoxDetail.getNameGoodsCn();
                fnsku = fbaBoxDetail.getFnsku();
                asin = fbaBoxDetail.getAsin();
                sku = fbaBoxDetail.getSku();
                num = fbaBoxDetail.getNumPlanDeliver().toString();
                signCode = fbaBoxDetail.getSignCode();
                code3 = code;

                //查询货件信息
                Map<String, Object>  params3 = new HashMap<String, Object>();
                params3.put("guid", fbaBoxDetail.getCode());
                fbaShipmentDetail = fbaShipmentDetailMapper.queryFirstByGuid(params3);
                listSysFilesInfo = sysFilesInfoService.listSysFilesInfoByFileMark(fbaShipmentDetail.getPdGuid());

                fileToumingbiaoArr = new ArrayList<ToPrintGoodsDto.RowDto.FileDto>();
                for (SysFilesInfo sysFilesInfo : listSysFilesInfo) {
                    String link = sysFilesInfo.getFilePath();
                    fileToumingbiaoArr.add(new ToPrintGoodsDto.RowDto.FileDto(link));

                }

                rows.add(new ToPrintGoodsDto.RowDto(guid, code2, name, fnsku, asin, sku, num, code3, signCode,fileToumingbiaoArr));
            }
        }
        ToPrintGoodsDto dto = new ToPrintGoodsDto(code, rows);
        mv.addObject("dto", dto);
        return mv;
    }

    /**
     * 美标箱规
     * @param request
     * @param response
     * @param model
     * @return
     */
    @RequestMapping("/astm")
    public ModelAndView toYys(HttpServletRequest request, HttpServletResponse response, ModelMap model) {
        try {
            List<FbaBoxDetail> fbaBoxDetailList= JSON.parseArray(request.getParameter("infoItems"), FbaBoxDetail.class);
            FbaBox fbaBox= JSON.parseObject(request.getParameter("infoMap").toString(), FbaBox.class);
            ModelAndView mv = new ModelAndView();
            mv.addObject("infoItems", fbaBoxDetailList);
            mv.addObject("infoMap", fbaBox);
            if (fbaBox.getCreationMethod().equals("手动")){
                mv.setViewName(prefix + "/astm");
            }else {
                mv.setViewName(prefix + "/astmZd");
            }
            return mv;
        } catch (Exception e) {
            e.printStackTrace();
            return null;    //详细信息
        }
    }


    /**
     * @Description: 批量导入表格
     * @Author: fxz
     * @date: 2023-04-24 14:39
     */
    @GetMapping("/toImportBatch")
    public ModelAndView toImportBatch(String codeBox,String codeShipment,String shipmentId) {

        ModelAndView mv = this.getModelAndView();
        mv.addObject("codeBox", codeBox);
        mv.addObject("codeShipment", codeShipment);
        mv.addObject("shipmentId", shipmentId);
        mv.setViewName(prefix + "/toImportBatch");
        return mv;

    }

    @PostMapping("/uploadAndReadExcelBatchImport")
    @ResponseBody
    public AjaxResult uploadAndReadExcelBatchImport(@RequestParam("file") MultipartFile uploadfile, String shipmentId) throws Exception {
        try {
            InputStream fileInputStream = uploadfile.getInputStream();

            // 文件初始名
            String sourceFilename = uploadfile.getOriginalFilename();
            if (!sourceFilename.endsWith(".xlsx")) {
                return AjaxResult.error("请按照模板xlsx进行导入");
            }
            //第一页
            List<List<String>> data = ReadExcel.getRowsByInputStream(fileInputStream, 0);

            //每行所有箱子数据
            List<BigDecimal> boxList = null;
            //总个箱子数量
            BigDecimal numRealityDeliver = BigDecimal.ZERO;
            //判断数据格式是否正确
            if (data.size() <= 5){
                return AjaxResult.error("导入无商品数据,请按照模板xlsx进行导入");
            }


            List<TableDto.RowDto> rows = new ArrayList<TableDto.RowDto>();

            //将sku的箱子数据整理
            for (int i = 1;data != null && i < data.size(); i++) {
                TableDto.RowDto rowDto = null;
//                if (i != data.size() - 5){
                    numRealityDeliver = BigDecimal.ZERO;
                    boxList = new LinkedList<>();
                    for (int j = 7; j < data.get(i).size(); j++) {
                        if (!data.get(i).get(j).equals("") &&  data.get(i).get(j) != null){
                            boxList.add(new BigDecimal(data.get(i).get(j)));
                            numRealityDeliver = numRealityDeliver.add(new BigDecimal(data.get(i).get(j)));
                        } else {
                            boxList.add(BigDecimal.ZERO);
                        }
                    }
//                }
                if (i <= data.size() - 5){
                    rowDto = new TableDto.RowDto(data.get(i).get(0),data.get(i).get(1),data.get(i).get(2),data.get(i).get(3)
                            ,data.get(i).get(4),data.get(i).get(5),
                            Integer.valueOf(new BigDecimal(data.get(i).get(6)).stripTrailingZeros().toPlainString()),numRealityDeliver,boxList);
                    rows.add(rowDto);
                } else  if(i == data.size() - 4){
                    rowDto = new TableDto.RowDto(data.get(i).get(0),data.get(i).get(1),data.get(i).get(2),data.get(i).get(3)
                            ,data.get(i).get(4),data.get(i).get(5),
                            null,null,boxList);
                    rows.add(rowDto);
                } else  if(i == data.size() - 3){
                    rowDto = new TableDto.RowDto(data.get(i).get(0),data.get(i).get(1),data.get(i).get(2),data.get(i).get(3)
                            ,data.get(i).get(4),data.get(i).get(5),
                            null,null,boxList);
                    rows.add(rowDto);
                } else  if(i == data.size() - 2){
                    rowDto = new TableDto.RowDto(data.get(i).get(0),data.get(i).get(1),data.get(i).get(2),data.get(i).get(3)
                            ,data.get(i).get(4),data.get(i).get(5),
                            null,null,boxList);
                    rows.add(rowDto);
                } else  if(i == data.size() - 1){
                    rowDto = new TableDto.RowDto(data.get(i).get(0),data.get(i).get(1),data.get(i).get(2),data.get(i).get(3)
                            ,data.get(i).get(4),data.get(i).get(5),
                            null,null,boxList);
                    rows.add(rowDto);
                }
            }

            if (rows != null && rows.size() > 300) {
                return AjaxResult.error("导入数量不能超过300条");
            }

            TableDto dto = new TableDto(rows,shipmentId,boxList.size());
            return AjaxResult.success(dto);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error();
        }
    }

    @Data
    @AllArgsConstructor
    public static class TableDto{
        private List<RowDto> rows; // 头程装箱清单数组
        private String shipmentId; // fba
        private Integer colsSize; // 多少个箱子

        @Data
        @AllArgsConstructor
        public static class RowDto {
            private String serial; // 序号
            private String commodityCode; // 商品编码
            private String name; // 商品名称
            private String sku; // SKU
            private String asin; // asin
            private String fnsku; // fnsku
            private Integer numPlanDeliver; // 计划发货数量
            private BigDecimal numRealityDeliver; // 实际发货数量
            private List<BigDecimal> boxList; // 总的箱子数据
        }
    }

    /**
     * @Description: 头程装箱清单导入
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: fxz
     */
    @RequiresPermissions(value = {"business:fbaplanorder:add", "business:fbaplanorder:edit", "business:fbaplanorder:delete"}, logical = Logical.OR)
    @Log(title = "头程装箱清单导入", businessType = BusinessType.UPDATE)
    @PostMapping("/inbound")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult inbound(@RequestParam Map<String, Object> params) {
        params.put("moduleTable", moduleTable);
        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult = fbaBoxService.saveDataInbound(params);
        } catch (Exception e) {
            ajaxResult = AjaxResult.error(this.getExceptionMessage(e));
        }
        return ajaxResult;
    }

    /**
     * @Description: 装箱清单数据导出Excel
     * @Param: [params]
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: hlf
     * @date: 2022-08-15 15:43
     */
    @RequiresPermissions("business:fbaplanorder:export")
    @Log(title = "头程装箱数据导出", businessType = BusinessType.EXPORT)
    @GetMapping("/exportInbound")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult exportInbound(@RequestParam Map<String, Object> params) throws Exception {
        params.put("moduleTable", moduleTable2);
        params.put("entity", new FbaBoxDetail()); //生成表格gridColumns对应的实体，用于获取实体属性生成表格字段
        params.put("num",0);
        List<FbaBoxDetail> list = fbaBoxDetailService.queryList(params);
        params.put("moduleTable", "TP_FbaInbound");
        list = list.stream().filter(fbaBoxDetail2 -> !fbaBoxDetail2.getSerial().equals("合计")).collect(Collectors.toList());

        params.put("getFieldAttributesType","export");
        List<SysDictionaryForExport> fieldList = dictionaryForFieldService.queryExportFieldList(params);
        ExportExcelUtils<FbaBoxDetail> util = new ExportExcelUtils<FbaBoxDetail>("TP_FbaInbound", new FbaBoxDetail());
        return util.exportExcel(list, fieldList, "头程装箱清单模板", "export");
    }

    /**
     * @Description: 打开选择列表
     * @Param: [params]
     * @return: org.springframework.web.servlet.ModelAndView
     * @Author: fxz
     * @date: 2023-09-20 15:42
     */
    @GetMapping("/select")
    public ModelAndView selectList(@RequestParam Map<String, Object> params) {
        params.put("moduleTable", moduleTableS);
        params.put("entity", new FbaBox()); //生成表格gridColumns对应的实体，用于获取实体属性生成表格字段
        params.put("toolBarWidth", 0);
        if (params.get("pagetype") != null && params.get("pagetype").toString().equalsIgnoreCase("checkbox"))
            params.put("checkBox", "yes");
        else params.put("radio", "yes");
        ModelAndView mv = this.getModelAndView();
        AjaxResult ajaxResult = new AjaxResult();
        Map<String, Object> dictionaryForFieldMap = new HashMap<String, Object>();

        mv.addObject("fields", TypeUtils.mapToJson(dictionaryForFieldMap));
        mv.addObject("ajaxResult", ajaxResult);
        mv.addObject("gridColumns", gridColumnsPropertyModel.queryGridColumnsPropertyModel(params));
        mv.addObject("prefix", prefix);
        mv.addObject("moduleTable", moduleTableS);
        mv.setViewName("common/select");
        return mv;
    }
}